//
// Created by hunan on 25-3-22.
//

#ifndef TLS_SOCKET_SERVER_CONNECTION_H
#define TLS_SOCKET_SERVER_CONNECTION_H

#include "description_module/description_module.h"
#include "socket_module/socket_server_connection.h"
#include "write_read_module/buffer.h"

#include <memory>
#include <set>

class Loop;
class SocketDescription;
class TlsSocketServerChannel;
class TlsSocketServerConnectionChannel;
class TlsSocketOperate;
class TlsSocketServer : public SocketServer,
                      public std::enable_shared_from_this<TlsSocketServer>
{
public:
    explicit TlsSocketServer(Loop * loop);
    ~TlsSocketServer() override = default;
    int BindAddress(const TlsSocketServer::Option & option) override;
    int Listen() override;
    struct CmpConnection
    {
        bool operator()(const std::shared_ptr<SocketServerConnection> & a,
                        const std::shared_ptr<SocketServerConnection> & b) const
        {
            return a.get() != b.get();
        }
    };
    Loop * GetLoop() const;

private:
    friend class TlsSocketServerChannel;
    Loop *                                                           m_loop;
    std::shared_ptr<SocketDescription>                               m_description;
    std::shared_ptr<TlsSocketServerChannel>                          m_channel;
    std::shared_ptr<TlsSocketOperate>                                m_operate;
    SocketServer::Option                                             m_option;
    std::set<std::shared_ptr<SocketServerConnection>, CmpConnection> m_connection_set;
};

class TlsSocketServerConnection : public SocketServerConnection,
                                  public std::enable_shared_from_this<TlsSocketServerConnection>
{
public:
    explicit TlsSocketServerConnection(TlsSocketServer * server, const std::shared_ptr<Description> & description);
    int  AsyncWrite(const uint8_t * data, int data_length) override;
    int  AsyncRead() override;
    void Close() override;
    void UpdateOption(const ClientOption &option) override;
private:
    friend class TlsSocketServerConnectionChannel;
    TlsSocketServer *                                   m_server;
    std::shared_ptr<Description>                      m_description;
    std::shared_ptr<TlsSocketServerConnectionChannel> m_channel;
    std::shared_ptr<TlsSocketOperate>                 m_tls_operate;
    SocketServerConnection::ClientOption              m_client_option{};
    WriteReadBuffer                                   m_write_buffer;
    WriteReadBuffer                                   m_read_buffer;
};

#endif // TLS_SOCKET_SERVER_CONNECTION_H
